package itsm.isperp.job;

import itsm.isperp.framework.core.context.ContextHolder;
import itsm.isperp.framework.message.IMessageSender;
import itsm.isperp.framework.message.domain.MessageType;
import itsm.isperp.module.entity.app.AppMessage;
import itsm.isperp.module.entity.app.AppMessageFailed;
import itsm.isperp.module.entity.app.AppMessageSuccess;
import itsm.isperp.module.repository.app.AppMessageFailedMapper;
import itsm.isperp.module.repository.app.AppUserMapper;
import itsm.isperp.module.service.app.AppMessageSenderService;
import itsm.isperp.module.service.app.AppMessageService;
import itsm.isperp.module.service.app.AppMessageSuccessService;

import java.util.List;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * 消息队列作业
 *
 * @author lizx
 * @date 2013-7-31
 *
 */
@Service
public class MessageQueuesJob implements Job {

	public static final Logger logger = LoggerFactory
			.getLogger(MessageQueuesJob.class);

	@Autowired
	protected AppUserMapper appUserMapper;

	@Autowired
	protected AppMessageSenderService appMessageSenderService;

	@Autowired
	protected AppMessageSuccessService appMessageSuccessService;

	@Autowired
	protected AppMessageFailedMapper appMessageFailedMapper;

	@Autowired
	protected AppMessageService appMessageService;

	protected static volatile boolean sending = false;

	/*
	 * (non-Javadoc)
	 *
	 * @see org.quartz.Job#execute(org.quartz.JobExecutionContext)
	 */
	@Override
	public void execute(JobExecutionContext context)
			throws JobExecutionException {

		if (sending) {
			return;
		}
		sending = true;
		try {
			List<AppMessage> messages = appMessageService.findAll();
			send(messages);
		} catch (Exception ex) {
		}

		sending = false;
	}

	/**
	 * 发送消息列表
	 *
	 * @param messages
	 *            消息列表
	 */
	private void send(List<AppMessage> messages) {
		if (messages.size() == 0) {
			return;
		}

		IMessageSender emailSender = ContextHolder
				.getSpringBean("isperp.emailSender");
		IMessageSender smsSender = ContextHolder
				.getSpringBean("isperp.smsSender");

		for (AppMessage msg : messages) {
			switch (msg.getMessageType()) {
			case MessageType.EMAIL:
				try {
					emailSender.send(msg);
					sendSuccess(msg);
				} catch (Exception ex) {
					sendFail(msg, ex.getMessage());
				}
				break;

			case MessageType.SMS:
				try {
					smsSender.send(msg);
					sendSuccess(msg);
				} catch (Exception ex) {
					sendFail(msg, ex.getMessage());
				}
				break;
			case MessageType.MSG:
				appMessageSenderService.sendTo(msg);
				sendSuccess(msg);
				break;

			}

		}
	}

	/**
	 * 发送成功处理方法，移除消息至消息发送成功表
	 *
	 * @param msg
	 */
	private void sendSuccess(AppMessage msg) {
		this.appMessageService.delete(msg.getId());
		// 添加发送成功记录
		this.appMessageSuccessService.saveOrUpdate(new AppMessageSuccess(msg));

	}

	/**
	 * 发送失败处理方法，如果消息发送次数超过3此则移至消息发送失败表
	 *
	 * @param msg
	 *            消息
	 * @param error
	 *            错误堆栈信息
	 */
	private void sendFail(AppMessage msg, String error) {

		if (msg.getFailCount() > 3) {
			this.appMessageService.delete(msg.getId());
			AppMessageFailed f = new AppMessageFailed(msg, error);
			this.appMessageFailedMapper.save(f);
		} else {
			this.appMessageService.failCountIncrease(msg.getId());
		}
	}

}
